package com.humanminoritygame.web;

import java.util.Random;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.humanminoritygame.common.Utils;
import com.humanminoritygame.model.User;
import com.humanminoritygame.model.UserRepo;

@Controller
public class IndexController {
  UserRepo userRepo;
  private static final Pattern EMAIL_PATTERN = Pattern.compile("^\\w+([_\\.-]\\w+)*@(\\w+([_\\.-]\\w+)*)");
  private static final Pattern USER_NAME_PATTERN = Pattern.compile("\\w+");
  
  @Autowired
  public IndexController(UserRepo userRepo){
    this.userRepo = userRepo;
  }

  @RequestMapping(method = RequestMethod.GET)
  public ModelAndView index(){
    ModelAndView mav = new ModelAndView();
    mav.setViewName("indexIndex");
    return mav;
  }

  @RequestMapping(method = RequestMethod.POST)
  public ModelAndView index2(){
    ModelAndView mav = new ModelAndView();
    mav.setViewName("indexIndex");
    return mav;
  }

  @RequestMapping(method = RequestMethod.GET)
  public ModelAndView welcome(){
    ModelAndView mav = new ModelAndView();
    mav.setViewName("indexWelcome");
    return mav;
  }

  @RequestMapping(method = RequestMethod.POST)
  public ModelAndView welcome2(){
    ModelAndView mav = new ModelAndView();
    mav.setViewName("indexWelcome");
    return mav;
  }

  @RequestMapping(method = RequestMethod.POST)
  public String signup(HttpServletRequest request, @RequestParam("user")String name, @RequestParam("email")String email, @RequestParam("pass1")String pass1, @RequestParam("pass2")String pass2){
    boolean error = false;
    String errores = new String();

    if(!Utils.validatePattern(name, USER_NAME_PATTERN)){
      error = true;
      errores = errores + "The user name can only contain leters or numbers<br/>";
    }

    if(name.length()>50){
      error = true;
      errores = errores + "Please choose a shorter name<br/>";
    }

    if(userRepo.getUserByName(name)!=null){
      error = true;
      errores = errores + "The user name already exists, please choose anotherone<br/>";
    }
    if(!Utils.validatePattern(email, EMAIL_PATTERN) || email.length()>100){
      error = true;
      errores = errores + "Please enter a valid email address<br/>";
    }

    if(pass1.length()==0 || pass2.length()==0 || pass1.length()>50 || pass2.length()>50){
      error = true;
      errores = errores + "Please enter a valid password<br/>";
    }

    if(!pass1.equals(pass2)){
      error = true;
      errores = errores + "Password mismatch<br/>";
    }

    if(!error){
      userRepo.addUser(new User(name, Utils.encrypt(pass1), email));
      request.setAttribute("signupok", "Registration successful. Check your email for confirmation.");
      User user = userRepo.getUserByName(name);
      String fullUrl = new String(request.getRequestURL().toString());
      Utils.enviarMail(user, fullUrl);
    } else {
      request.setAttribute("name", name);
      request.setAttribute("email", email);
      request.setAttribute("signuperror", errores);
    }

    return "forward:index2";
  }

  @RequestMapping(method = RequestMethod.GET)
  public ModelAndView confirm(HttpServletRequest request, @RequestParam("n")Integer n, @RequestParam("uid")String uid){
    ModelAndView mav = new ModelAndView();
    mav.setViewName("indexConfirm");
    User u = userRepo.getUserByName(uid);
    if(u.getConfirmedMail().equals(n)){
      u.setConfirmedMail(-1);
      request.setAttribute("user", u);
      mav.addObject("confirmation","Confirmation OK");
    } else {
      mav.addObject("confirmation", "Confirmation FAIL");
    }

    return mav;
  }
  
  @RequestMapping(method = RequestMethod.GET)
  public ModelAndView help(){
    ModelAndView mav = new ModelAndView();
    mav.setViewName("indexHelp");
    return mav;
  }

  @RequestMapping(method = RequestMethod.POST)
  public String login(HttpSession session, HttpServletRequest request, @RequestParam("user")String name, @RequestParam("pass")String pass){
    User user;
    if((user=userRepo.getUser(name, Utils.encrypt(pass))) != null && !user.isRobot() && user.getConfirmedMail().equals(-1)){
      session.setAttribute("user", user);
      return "forward:welcome2";
    } else {
      request.setAttribute("loginerror", "Username/password incorrect or not confirmed mail");
      return "forward:index2";
    }
  }

  @RequestMapping(method = RequestMethod.GET)
  public String logout(HttpSession session, HttpServletRequest request){
    User user = (User)session.getAttribute("user");
    if(user != null){
      session.removeAttribute("user");
    }

    return "redirect:index";
  }

  @RequestMapping(method = RequestMethod.GET)
  public ModelAndView forgotPass(){
    ModelAndView mav = new ModelAndView();
    mav.setViewName("indexForgotPass");
    return mav;
  }
  @RequestMapping(method = RequestMethod.POST)
  public ModelAndView forgotPass2(){
    ModelAndView mav = new ModelAndView();
    mav.setViewName("indexForgotPass");
    return mav;
  }

  @RequestMapping(method = RequestMethod.POST)
  public String rememberPassword(HttpServletRequest request, @RequestParam("username")String username){
    User u = userRepo.getUserByName(username);
    Random r = new Random();
    if(u==null){
      request.setAttribute("rememberpassworderror", "Invalid username");
      request.setAttribute("rememberpasswordbackup", username);
      return "forward:forgotPass2";
    }

    Integer num = r.nextInt(9999999 - 100001) + 100001;
    u.setPassword(Utils.encrypt(num.toString()));

    Utils.enviarForgotPassMail(u, num.toString());
    request.setAttribute("rememberpasswordok", "You will receive an email shortly. Remember to check your SPAM folder.");
    return "forward:forgotPass2";
  }


  @RequestMapping(method = RequestMethod.GET)
  public ModelAndView resendConfirmation(){
    ModelAndView mav = new ModelAndView();
    mav.setViewName("indexResendConfirmation");
    return mav;
  }
  @RequestMapping(method = RequestMethod.POST)
  public ModelAndView resendConfirmation2(){
    ModelAndView mav = new ModelAndView();
    mav.setViewName("indexResendConfirmation");
    return mav;
  }

  @RequestMapping(method = RequestMethod.POST)
  public String confirmationMail(HttpServletRequest request, @RequestParam("email")String email, @RequestParam("uname")String uname, @RequestParam("pass")String pass){
    User u;
    Random r = new Random();
    if((u=userRepo.getUser(uname, Utils.encrypt(pass))) == null){
      request.setAttribute("resendconfirmationmailerror", "Wrong username/password");
      request.setAttribute("resendconfirmationmailnamebkup", uname);
      return "forward:resendConfirmation2";
    }
    
    if(!Utils.validatePattern(email, EMAIL_PATTERN)){
      request.setAttribute("resendconfirmationmailerror", "Invalid email address");
      request.setAttribute("resendconfirmationmailnamebkup", uname);
      return "forward:resendConfirmation2";
    }

    if(!u.getMail().equals(email)){
      u.setMail(email);
    }

    u.setConfirmedMail(r.nextInt());
    Utils.enviarMail(u, request.getRequestURL().toString());
    request.setAttribute("resendconfirmationok", "Confirmation email sent. Please check your inbox and spam folder.");
    return "forward:resendConfirmation2";
  }
}
